import { action, observable } from "mobx";
import * as _ from "lodash";
import { getColIndex, getRowIndex } from "../../util/typeUtil";
import { parseCell } from "./Parse";

export interface DatajsonProps {
    eformdesign: {
        eattr: any,
        etables: any,
        formula: any
    }
}

export interface RowColProps {
    id: string;
    size: any;
    index: number;
    hide?: string;
    obj: any;
}
export interface CellProps {
    row: number;
    col: number;
    style?: React.CSSProperties
    otherProps: {
        valign?: string,
        rowspan?: number,
        colspan?: number,
        className?: string;
        name?: string;
        id?: string;
    }
    cellProps: {
        style?: React.CSSProperties,
    }
    backgroundColor?: string;
    etype: string;
    evalue: string;
    field: string;
    fieldtype: string;
    financial?: string;
    detail: any;
    tab: any;
    format: any;
    stylejson: any;
    getPath: () => string;
    mcpoint?: string;
    brsign?: string;
    jsonparam?: any;
    hidechild?: string;
}
export interface DetailProps {
    isOpensapmul: boolean;
    isAdd: boolean;
    isDelete: boolean;
    isCopy: boolean;
    isOpenCustomOrder: boolean;
    isDefault: boolean;
    isHideNull: boolean;
    isNeed: boolean;
    isPrintserial: boolean;
    orderid: string;
    isPagination: boolean;
}
export class ModeMutilContent {
    rowcount: number = 0;
    colcount: number = 0;
    @observable cells: any[] = [];
    initMc = (detail: any = {}) => {
        this.rowcount = detail.rowcount;
        this.colcount = detail.colcount;
        const { ec = [] } = detail;
        const _cells: any[][] = [];
        _.each(ec, (cell: any) => {
            if (cell) {
                const ids = cell.id.split(',');
                if (ids.length == 2) {
                    _.set(_cells, `[${ids[0]}].[${ids[1]}]`, parseCell(cell));
                }
            }
        });
        const _mcCells: CellProps[] = [];
        _cells.map((rowcells: any[]) => {
            rowcells.map(cell => {
                _mcCells.push(cell);
            });
        });

        this.cells = _mcCells;
    }

}
export default class ModeExcel {

    @observable isInit = false;

    @observable cols: RowColProps[] = [];
    @observable rows: RowColProps[] = [];
    @observable proportion: number = 1;
    @observable sumWidth: number = 0;

    @observable details: any = {};
    @observable mutilContents: any = {};
    @observable tabs: any = {};
    @observable floatingObjectArray: any = [];
    @observable cells: CellProps[] = [];

    edtailinrow?: string;
    edtitleinrow?: string;
    seniorset?: string;
    backgroundImg?: string;
    edlockedcol?: number = -1;//锁定列
    @observable detailProps: DetailProps = {} as any;

    @observable error: { visible: boolean, msg: string } = { visible: false, msg: '' }

    @observable path = '';
    //定义固定列所在位置（从左往右数，下标从0开始）
    @observable fixFieldIndex: number = 0;
    //定义合并行的字段
    @observable mergeFields: any = {};
    @observable fixFieldWidth: number = 0;

    formula: any = {};
    combineCell?: string[];
    isHaveDetailCheck = false;
    @observable containerWidth: number = document.documentElement.clientWidth - 300;

    @observable tableStyle: any = {};
    @observable detailMap: any = {};//存放明细表锁定列信息
    @observable type: any;
    @observable mergeType: any;//明细表字段合并方式  1：相邻行合并   2所有行合并
    // @observable detaicolorlMap: any = {};//存放明细表td style
    @observable isDragulaMap: any = {};//存放明细表排序信息  
    @observable detailFinancialMap: any = {};//存放模板格式上面的千分位,金额大写信息 
    codeImgFn:any = {};
    @action
    init = (datajson: DatajsonProps, type) => {
        const { eformdesign } = datajson;
        const { etables, formula } = eformdesign;
        const { emaintable = {}, ...details } = etables;
        const { colheads = {}, rowheads = {}, rowattrs = {}, ec = [], colattrs = {}, combine_cell = [], isHaveDetailCheck = false, backgroundImage, floatingObjectArray = {} } = emaintable;
        this.formula = formula;
        this.type = type
        this.initCol(colheads);
        this.initRow(rowheads, rowattrs);
        this.initCell(ec, colattrs);
        this.combineCell = combine_cell;
        this.isHaveDetailCheck = isHaveDetailCheck;
        this.initDetail(details, type);
        this.backgroundImg = backgroundImage;
        this.floatingObjectArray = floatingObjectArray;
        this.isInit = true;
    }

    @action
    initDetail = (details: any, type?) => {
        let _details: any = {};
        let _mutilcontents = {};
        const _tabs = {};
        _.each(details, (detail: any, name: string) => {
            if (name.startsWith('detail_')) {
                const excel: ModeExcel = new ModeExcel();
                let { colheads = {}, rowheads = {}, ec = [], colattrs = {}, combine_cell = [], isHaveDetailCheck = false } = detail;
                // console.log(toJS(colheads),toJS(rowheads),toJS(colattrs),name)
                // if(isOpenCustomOrder&&!isHaveDetailCheck){
                //     colheads={'col_-1':'50',...colheads};
                //     console.log(toJS(colheads),name)
                // }
                //获取明细表的固定列
                excel.fixFieldIndex = _.get(detail, 'edlockedcol');
                excel.mergeFields = _.get(detail, 'mergeFields');

                excel.initCol(colheads, this.sumWidth, true, colattrs, excel.fixFieldIndex, type);
                excel.initRow(rowheads);
                excel.initCell(ec, colattrs)
                excel.seniorset = _.get(detail, 'seniorset');
                excel.edtitleinrow = _.get(detail, 'edtitleinrow');
                excel.edtailinrow = _.get(detail, 'edtailinrow');
                excel.edlockedcol = _.get(detail, 'edlockedcol');
                excel.combineCell = combine_cell;
                excel.isHaveDetailCheck = isHaveDetailCheck;
                excel.path = name;
                excel.mergeType = _.get(detail, 'mergeType');
                _.set(_details, name, excel);
            } else if (name.startsWith('mc_')) {
                const excel: ModeMutilContent = new ModeMutilContent();
                excel.initMc(detail);
                _.set(_mutilcontents, name, excel);
            } else if (name.startsWith('tab_')) {

                const excel: ModeExcel = new ModeExcel();
                const { colheads = {}, rowheads = {}, ec = [], colattrs = {}, combine_cell = [], rowattrs = {} } = detail;
                excel.initCol(colheads, this.sumWidth, true, colattrs, 0, type);
                excel.initRow(rowheads, rowattrs);
                excel.initCell(ec, colattrs);
                excel.combineCell = combine_cell;
                excel.path = name;
                _.set(_tabs, name, excel);
            }
        });
        this.details = _details;
        this.mutilContents = _mutilcontents;
        this.tabs = _tabs;
    }

    getSortField = (ec: any[] = []) => {
        return ec.sort((a, b) => { //单元格按单元格位置排序
            const [row1, col1] = a.id.split(',');
            const [row2, col2] = b.id.split(',');
            const ri1 = parseInt(row1, 10);
            const ci1 = parseInt(col1, 10);
            const ri2 = parseInt(row2, 10);
            const ci2 = parseInt(col2, 10);
            if (ri1 !== ri2) {
                return ri1 - ri2;
            } else {
                return ci1 - ci2;
            }
        });
    }

    @action
    initCell = (ec: any[] = [], colattrs: any = {}) => {
        let newKeys = this.getSortField(ec);
        let fixBlankCell = (newEc) => {    //补全空单元格
            let mark = -1, count = 0;
            let ec_copy = newEc.slice();
            ec_copy.forEach((c, index, arr) => {
                let v = c.id.split(",");
                if (v[0] != mark) {
                    mark = v[0];
                    while (v[1] > count) {
                        newEc.splice(index + count, 0, {
                            "colspan": "1",
                            "eborder": [],
                            "rowspan": "1",
                            "etype": "0",
                            "evalue": "",
                            "id": mark + "," + count,
                            "font": {}
                        });
                        count++;
                    }
                    if (v[1] <= count) {
                        count = 0;
                    }
                } else {
                    if (index > 0 && (v[1] - 1) > arr[index - 1].id.split(",")[1]) {
                        for (let i = 0; i < v[1] - 1 - arr[index - 1].id.split(",")[1]; i++) {
                            let temp = parseInt(arr[index - 1].id.split(",")[1], 10) + 1 + i;
                            newEc.splice(index - 1 + i, 0, {
                                "colspan": "1",
                                "eborder": [],
                                "rowspan": "1",
                                "etype": "0",
                                "evalue": "",
                                "id": mark + "," + temp,
                                "font": {}
                            });
                        }
                    }
                }
            });
            return newEc;
        };
        ec = this.getSortField(fixBlankCell(newKeys))
        const cells = ec.map((cell: any) => {
            let rowcol = cell.id.split(',') as string[];
            let rows = this.rows.slice().filter((row) => row.id == `row_${rowcol[0]}`);
            let rowHeight = 30;
            if (rows.length > 0) {
                rowHeight = rows[0].size;
            }
            let colAttr = colattrs[`col_${rowcol[1]}`];
            let newcell=parseCell(cell, rowHeight, colAttr);
            if(newcell.financial){
                _.set(this.detailFinancialMap,`field${newcell.field}`,newcell.financial);
            }
            return newcell
        });
        const removeCells: string[] = []
        cells.forEach((cell: any) => {    //兼容老的excel解析列
            if (cell.otherProps && cell.otherProps.colspan && cell.otherProps.colspan > 1) {
                for (let i = 1; i < cell.otherProps.colspan; i++) {
                    removeCells.push(`${cell.row},${cell.col + i}`);
                }
            }
        });
        this.cells = cells.filter(d => removeCells.indexOf(`${d.row},${d.col}`) < 0);
    }

    @action
    initRow = (rowheads: any, rowattrs?: any) => {
        let _rows: RowColProps[] = [];
        _.each(rowheads, (size: string, id: string) => {
            let height = 0;
            if (size.indexOf("%") > 0) {
                height = (parseFloat(size) * document.documentElement.clientHeight) / 100;
            } else {
                height = parseInt(size);
            }
            _rows.push({
                id,
                size: height,
                index: getRowIndex(id),
                obj: ""
            });
        });
        /**设计器自定义属性隐藏整行功能添加判断 */
        rowattrs && _.each(rowattrs, (obj: any, id: string) => {
            _rows = _rows.map(row => {
                if (row.id === id) {
                    return { ...row, obj }
                } else {
                    return { ...row }
                }
            })
        })
        this.rows = _rows.sort((a, b) => a.index - b.index);;
    }

    @action
    initCol = (colheads: any, mainWidth: number = this.containerWidth, isDetail: boolean = false, colattrs = {}, fixFieldIndex: number = 0, type?) => {
        let _cols: RowColProps[] = [];

        let allWidth: number = 0;
        let totalPx = 0;
        // let totalPercent = 0;
        let hasPercent = false;
        let tableStyle: any = {};
        let widthpxAll: number = 0
        let widthAll: any = {};
        _.each(colheads, (size, id) => {
            if (size.indexOf("%") === -1 && size !== "*") {
                widthpxAll += parseFloat(size);
                if (isDetail) widthAll[id.split("_")[1]] = parseFloat(size);
            }
        });
        _.each(colheads, (size: string, id: string) => {
            let width = 0;
            if (size.indexOf("%") > 0) {
                // totalPercent += parseFloat(size.replace("%",""));
                hasPercent = true;
            } else {
                width = parseInt(size);
                totalPx += parseFloat(size);
            }
            allWidth += width;
            // let validPercent = 100;   //处理下表单支持默认显示的百分比布局
            // if(isDetail)     //低级模式预留6%给序号列
            // validPercent = 94;
            let colWidth: any = size;
            // if(hasPercent&&colWidth.indexOf("%") === -1){
            //     colWidth = (parseFloat(colWidth)/totalPx) * (validPercent-totalPercent);
            //     colWidth = colWidth.toFixed(2)+"%";
            //     hasPercent = false;
            // }
            if (colWidth.indexOf("%") === -1 && colWidth !== "*") {
                //打印布局 换成百分比
                if (this.type == 4 || (type && type == 4)) {
                    colWidth = ((Number(size) / widthpxAll) * 100).toFixed(2) + '%'
                } else {
                    colWidth += "px";
                }
            }
            _cols.push({
                id,
                size: colWidth,
                index: getColIndex(id),
                obj: ""
            })

            this.sumWidth = allWidth;
            if (hasPercent) {
                tableStyle["width"] = "99%";
            } else {
                tableStyle["width"] = totalPx + "px";
            }
            //获取固定列的表格宽度
            if (isDetail) {
                let fixtotalPx = 0;
                for (let index = 0; index <= fixFieldIndex; index++) {
                    fixtotalPx += parseFloat(widthAll[index])
                }
                this.fixFieldWidth = fixtotalPx;
            }
            this.tableStyle = tableStyle;
        });


        /**设计器自定义属性隐藏整列 功能添加判断 =----明细表*/
        !_.isEmpty(colattrs) && _.each(colattrs, (obj: any, id: string) => {
            _cols = _cols.map(col => {
                if (col.id === id) {
                    return { ...col, ...obj }
                } else {
                    return { ...col }
                }
            })
        })
        this.cols = _cols.sort((a, b) => a.index - b.index);;
    }
    getExcel = (detail?: string): ModeExcel => {
        return detail ? _.get(this.details, detail) : new ModeExcel();
    }
    getTabs = (tab?: string): ModeExcel => {
        return tab ? _.get(this.tabs, tab) : new ModeExcel();
    }
    getTds = (row: number, detail, combineCell, detailIndex: number, rowspanJson: any): CellProps[] => {
        const tds: any[] = this.cells.slice().filter((cell: any) => {
            return cell.row == row;
        });
        tds.sort((a, b) => {
            return a.col - b.col;
        })
        let alltds: any[] = [];
        let j = 0;//代表每一列
        if (detail) {
            for (let i = 0; i < this.cols.length; i++) {
                let td = tds[j];
                let isadd = false;
                if (combineCell && this.containsValue(combineCell, row + ',' + i)) {//是合并单元格跳过不处理
                    if (td != undefined && td.col == i) {
                        isadd = true;
                        j++;
                    }
                    continue;
                }
                let rowspanIsZero = false;
                //合并行数据 rowspanJson[当前行下标] 获取本行涉及到的td以及对应的rowspan；    rowspanJson[detailIndex] 格式：[{5:2}] -- 表示当前行下标为5的td，rowspan=2
                if (rowspanJson[detailIndex]) {
                    for (let a = 0; a < rowspanJson[detailIndex].length; a++) {

                        //rowspan > 1 则将rowspan属性赋给td； 如果rowspan = 0，则跳过该td的渲染
                        if (rowspanJson[detailIndex][a][j] > 1) {
                            td.otherProps.rowspan = rowspanJson[detailIndex][a][j];
                            break;
                        } else if (rowspanJson[detailIndex][a][j] == 0) {
                            j++;
                            rowspanIsZero = true;
                            break;
                        } else {
                            td = {
                                ...td,
                                otherProps: {
                                    ...td.otherProps,
                                    rowspan: 1
                                }
                            }
                            //td.otherProps.rowspan = 1;
                        }
                    }
                } else if (td != undefined) {
                    if(Object.keys(rowspanJson).length>0){//明细存在合并信息时候
                        td = {
                            ...td,
                            otherProps: {
                                ...td.otherProps,
                                rowspan: 1
                            }
                        }
                    }else{// qc880486  明细一行拆分2行后，放多个字段 与明细合并显示字段冲突。两者互斥
                        td = {
                            ...td,
                            otherProps: {
                                ...td.otherProps
                            }
                        }
                    }
                }
                if (rowspanIsZero) continue;
                if (td == undefined || td.col != i) {//补空格
                    alltds.push(undefined);
                    continue;
                }
                if (!isadd) {
                    j++;
                }
                alltds.push(td);
            }
        } else {
            for (let i = 0; i < this.cols.length; i++) {
                let td = tds[j];
                let isadd = false;
                if (combineCell && this.containsValue(combineCell, row + ',' + i)) {//是合并单元格跳过不处理
                    if (td != undefined && td.col == i) {
                        isadd = true;
                        j++;
                    }
                    continue;
                }
                if (td == undefined || td.col != i) {//补空格
                    alltds.push(undefined);
                    continue;
                }
                if (!isadd) {
                    j++;
                }
                alltds.push(td);
            }

        }
        return alltds;
    }

    getFixFieldTds = (row: number, detail, combineCell, fixFieldIndex: number, detailIndex: number, rowspanJson: any): CellProps[] => {
        const tds: any[] = this.cells.slice().filter((cell: any) => {
            return cell.row == row;
        });
        tds.sort((a, b) => {
            return a.col - b.col;
        })
        let alltds: any[] = [];
        let j = 0;
        for (let i = 0; i <= fixFieldIndex; i++) {
            let td = tds[j];
            let isadd = false;
            if (combineCell && this.containsValue(combineCell, row + ',' + i)) {//是合并单元格跳过不处理
                if (td != undefined && td.col == i) {
                    isadd = true;
                    j++;
                }
                continue;
            }
            let rowspanIsZero = false;
            //合并行数据 rowspanJson[当前行下标] 获取本行涉及到的td以及对应的rowspan；    rowspanJson[detailIndex] 格式：[{5:2}] -- 表示当前行下标为5的td，rowspan=2
            if (rowspanJson[detailIndex]) {
                for (let a = 0; a < rowspanJson[detailIndex].length; a++) {

                    //rowspan > 1 则将rowspan属性赋给td； 如果rowspan = 0，则跳过该td的渲染
                    if (rowspanJson[detailIndex][a][j] > 1) {
                        td.otherProps.rowspan = rowspanJson[detailIndex][a][j];
                        break;
                    } else if (rowspanJson[detailIndex][a][j] == 0) {
                        j++;
                        rowspanIsZero = true;
                        break;
                    } else {
                        td = {
                            ...td,
                            otherProps: {
                                ...td.otherProps,
                                rowspan: 1
                            }
                        }
                    }
                }
            } else if (td != undefined) {
                if(Object.keys(rowspanJson).length>0){
                    td = {
                        ...td,
                        otherProps: {
                            ...td.otherProps,
                            rowspan: 1
                        }
                    }
                }else{// qc880486  明细一行拆分2行后，放多个字段 与明细合并显示字段冲突。两者互斥
                    td = {
                        ...td,
                        otherProps: {
                            ...td.otherProps
                        }
                    }
                }
            }
            if (rowspanIsZero) continue;
            if (td == undefined || td.col != i) {//补空格
                alltds.push(undefined);
                continue;
            }
            if (!isadd) {
                j++;
            }
            alltds.push(td);
        }
        return alltds;
    }

    containsValue = (arrs, value) => {
        let res = false;
        for (let i = 0; i < arrs.length; i++) {
            if (arrs[i] == value) {
                res = true;
                break;
            }
        }
        return res;
    }

    getMutilContent = (mcname: string): ModeMutilContent => {
        return _.get(this.mutilContents, mcname) || {};
    }

    addCodeFn = (params)=>{
        this.codeImgFn = {
            ...this.codeImgFn,
            ...params
        }
    }
}
